package com.zhu.load;

import java.io.FileInputStream;
import java.lang.reflect.Method;

/**
 * @ClassName MyClassLoadTest
 * @Description TODO
 * @Author zhuxiongbin
 * @Date 2021-11-03 10:11
 * @Version 1.0.0
 */
public class MyClassLoadTest {
    static class MyClassLoad extends ClassLoader{

        private String classPath;

        public MyClassLoad(String classPath) {
            this.classPath = classPath;
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            synchronized (getClassLoadingLock(name)) {
                // First, check if the class has already been loaded
                Class<?> c = findLoadedClass(name);
                if (c == null) {

                    long t0 = System.nanoTime();
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    if(!name.startsWith("com.zhu.load")){
                        c = this.getParent().loadClass(name);
                    }else{
                        c = findClass(name);
                    }

                    long t1 = System.nanoTime();

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();

                }
                return c;
            }
        }

        private byte[] loadByte(String name) throws Exception{
            name = name.replaceAll("\\.", "/");
            FileInputStream fileInputStream = new FileInputStream(classPath + "/" + name + ".class");
            int available = fileInputStream.available();
            byte[] date = new byte[available];
            fileInputStream.read(date);
            fileInputStream.close();
            return date;
        }


        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] date = loadByte(name);
                return defineClass(name,date,0,date.length);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ClassNotFoundException();
            }

        }
    }

    public static void main(String[] args) throws Exception {
        MyClassLoad myClassLoad = new MyClassLoad("D:/test");
        Class<?> aClass = myClassLoad.loadClass("com.zhu.load.myLodeTest");
        Object o = aClass.newInstance();
        Method method = aClass.getDeclaredMethod("lode", null);
        method.invoke(o,null);
        System.out.println(aClass.getClassLoader().getClass().getName());
    }
}
